package com.syp.auth.common.dbrouter.router;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import com.syp.auth.common.dbrouter.DBContextHolder;
import com.syp.auth.common.dbrouter.DBRouter;
import com.syp.auth.common.dbrouter.bean.DBRule;
import com.syp.auth.common.dbrouter.utils.DBRouterUtils;

@Service("dbRouter")
public class TradeDBRouterImpl implements DBRouter, ApplicationContextAware {

    private static final Logger logger	= LoggerFactory.getLogger(TradeDBRouterImpl.class);

    private ApplicationContext applicationContext;

    @Override
    public String doRoute(String fieldId, String dbRuleName) {

        DBRule dbRule = applicationContext.getBean(dbRuleName, DBRule.class);

        if (fieldId == null || dbRule == null || dbRule.getDataSourceKeys() == null
                || dbRule.getDataSourceKeys().size() <= 0) {
            throw new IllegalArgumentException("dbsCount and tablesCount must be both positive!");
        }
        try {
            // 对分库分表字段哈希后取绝对值
            int hashValue = DBRouterUtils.getHashValue(fieldId);
            // 用字段哈希后绝对值对总表数取余数，再除每库表数取商数，得到库索引值
            int dbIndex = DBRouterUtils.getDBIndex(dbRule, hashValue);
            // 用字段哈希后绝对值对每库表数取余数，由于数据源设置是从1开始，所以后面+1操作
            int tableIndex = DBRouterUtils.getTableIndex(dbRule,hashValue);
            // 获取对应的dataSource的KEY值
            String dsKey = dbRule.getDataSourceKeys().get(dbIndex);
            // 设置为dbKey对应的数据源为当前数据源
            DBContextHolder.setDbKey(dsKey);
            String tableFormat = DBRouterUtils.formatTableName(dbRule.getTableNameStyle(),tableIndex);
            DBContextHolder.setTableIndex(tableFormat);
            logger.info("DBRouter,fieldId:{},hashCode:{}",fieldId,hashValue);
            logger.info("DBRouter,dsKey:{},tableFormat:{}",dsKey,tableFormat);
            return dsKey;

        } catch (Exception e) {
            logger.error("DBRouter error,fieldId:{},Exception:{}",fieldId,e);
        }
        return null;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
